/**
 * Vite 插件：自动给 console.log 添加文件路径和行号
 */
import type { Plugin } from 'vite';
export default function consoleLocation(options = { methods: ['log', 'info', 'warn', 'error'] }): Plugin {
  return {
    name: "vite-plugin-console-location", // 插件名称（必填，用于调试和警告）
    enforce: 'pre',
    transform(code: string, id: string) {
      // 1. 过滤文件：仅处理 JS/TS 文件，排除 node_modules 和非脚本文件（如样式、图片）
      // id 是文件的完整路径，可能包含查询参数（如 .vue?vue&type=script）
      const cleanId = id.split('?')[0];
      const isNeedProcess = /\.(js|jsx|ts|tsx|vue)$/.test(cleanId) && !id.includes('node_modules');
      if (!isNeedProcess) {
        return undefined; // 不处理的文件直接返回，交给下一个插件
      }

      // 2. 处理 Vue 文件的特殊情况：仅提取 <script> 标签内的代码（避免修改模板/样式）
      let scriptCode = code;
      const isVueSfc = cleanId.endsWith('.vue');
      if (isVueSfc) {
        const scriptMatch = code.match(/<script[^>]*>([\s\S]*?)<\/script>/);
        if (!scriptMatch) return undefined; // 无 script 标签则跳过
        scriptCode = scriptMatch[1]; // 只处理脚本内容
      }

      // 3. 简化文件路径（去掉项目根目录，保留相对路径，如 "src/utils/format.js"）
      const projectRoot = process.cwd();
      const relativePath = cleanId.replace(projectRoot, '').replace(/^[\\/]/, '');

      // 4. 按行分割代码，匹配并修改 console.log
      const lines = scriptCode.split('\n');
      const transformedLines = lines.map((line: string, lineNumber: number) => {
        // 正则匹配 console.log(...)（支持 console.log、console.info 等）
        const methodStr = options.methods.join('|');
        const consoleReg = new RegExp(`console\\.(${methodStr})\\(`, 'g');
        if (consoleReg.test(line)) {
          const realLineNum = lineNumber + 1; // 行号从 1 开始
          // 注入 [路径:行号] 到 console 参数最前面
          return line.replace(consoleReg, `console.$1('[${relativePath}:${realLineNum}]', `);
        }
        return line; // 不匹配的行直接返回
      });

      // 5. 重新拼接代码（若为 Vue 文件，需将修改后的脚本插回原代码）
      let transformedCode = transformedLines.join('\n');
      if (isVueSfc) {
        transformedCode = code.replace(/<script[^>]*>([\s\S]*?)<\/script>/,
          (match: string, p1: string) => match.replace(p1, transformedCode)
        );
      }

      // 6. 返回处理结果（source-map 设为 null，Vite 会自动生成默认 map）
      return {
        code: transformedCode,
        map: null
      };
    }
  };
}